package cn.piesat.filter;

import cn.piesat.util.JedisUtils;
import cn.piesat.util.ResponseWrapperUtil;
import cn.piesat.util.ReturnCodeEnum;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.nimbusds.jose.JWSObject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import redis.clients.jedis.Jedis;

import java.nio.charset.StandardCharsets;
import java.text.ParseException;

/**
 * 校验Token过滤器
 *
 * @author xhl
 */
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    private Logger logger = LoggerFactory.getLogger(AuthGlobalFilter.class);

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        if (StringUtils.isBlank(token)) {
            return chain.filter(exchange);
        }
        token = token.replace("Bearer ", "");
        JWSObject jwsObject = null;
        try {
            jwsObject = JWSObject.parse(token);
        } catch (ParseException e) {
            return chain.filter(exchange);
        }
        String payload = jwsObject.getPayload().toString();
        JSONObject jsonObject = JSON.parseObject(payload);
        String jti = jsonObject.getString("jti");
        String userId = jsonObject.getString("userId");
        String userName = jsonObject.getString("user_name");
        Jedis jedis = JedisUtils.getJedis();
        try {
            Boolean exists = jedis.exists("auth:token:blacklist:" + jti);
            if (exists) {
                ServerHttpResponse response = exchange.getResponse();
                response.setStatusCode(HttpStatus.OK);
                response.getHeaders().set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
                response.getHeaders().set("Access-Control-Allow-Origin", "*");
                response.getHeaders().set("Cache-Control", "no-cache");
                String body = ResponseWrapperUtil.resultCustomEnumString(ReturnCodeEnum.INVALID_TOKEN,false);
                DataBuffer buffer = response.bufferFactory().wrap(body.getBytes(StandardCharsets.UTF_8));
                return response.writeWith(Mono.just(buffer));
            }
        } catch(Exception e) {
            logger.error("校验Token过滤器出现错误->{}", e);
        } finally {
            JedisUtils.close(jedis);
        }
        ServerHttpRequest request = exchange.getRequest().mutate()
                .header("payload", payload)
                .header("userId",userId)
                .header("userName",userName)
                .build();
        exchange = exchange.mutate().request(request).build();
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -2;
    }
}
